//
// Created by Ge on 2024/3/5.
//
#ifndef INC_3DMODEL_ANGLECUBE_H
#define INC_3DMODEL_ANGLECUBE_H

#include "glm/glm.hpp"
#include <GLES2/gl2.h>
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "LogUts.h"
#include "ShareLoader.h"
#include "Matrix.h"
#include "string"

class AngleCube {
public:
    void onSurfaceCreated(){
        init();
    }


    void draw() {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        GLuint vMatrixLoc = glGetUniformLocation(programID, "vMatrix");
        glEnableVertexAttribArray(vMatrixLoc);
        glUniformMatrix4fv(vMatrixLoc, 1, GL_FALSE, glm::value_ptr(mvp));

        GLuint vPositionLoc = glGetAttribLocation(programID, "vPosition");
        glEnableVertexAttribArray(vPositionLoc);
        glVertexAttribPointer(vPositionLoc, 3, GL_FLOAT, GL_FALSE, 3 * 4, vertices);

        GLuint aColorLoc = glGetAttribLocation(programID, "aColor");
        glEnableVertexAttribArray(aColorLoc);
        glVertexAttribPointer(aColorLoc, 4, GL_FLOAT, GL_FALSE, 4 * 4, colors);

        // 绘制正方体
        glDrawElements(GL_TRIANGLES, 24, GL_UNSIGNED_SHORT, indices);


        glDisableVertexAttribArray(vMatrixLoc);
        glDisableVertexAttribArray(aColorLoc);
        glDisableVertexAttribArray(vPositionLoc);
    }

    void onSurfaceChanged(int width, int height) {
        LOGD("onSurfaceChanged");
        glViewport(0, 0, width, height);
        radio = (float) width / (float) height;
        projection = glm::frustum(-radio, radio, -1.0f, 1.0f, 3.0f, 20.0f);
        view = glm::lookAt(glm::vec3(5.0f, 5.0f, 10.0f),  // Camera position
                           glm::vec3(0.0f, 0.0f, 0.0f),  // Look at position
                           glm::vec3(0.0f, 1.0f, 0.0f));
        //矩阵相乘不满足乘法交换律，前后顺序非常重要
        mvp = projection * view;
        frustumM(mProjectMatrix, 0, -radio, radio, -1.0f, 1.0f, 3.0f, 20.0f);
        setLookAtM(mViewMatrix, 0, 5.0f, 5.0f, 10.0f,
                   0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
        multiplyMM(mMVPMatrix, 0, mProjectMatrix, 0, mViewMatrix, 0);
    }


private:
    bool inited = false;
    char *vertexShaderCode = "attribute vec4 vPosition;\n"
                             "uniform mat4 vMatrix;\n"
                             "varying vec4 vColor;\n"
                             "attribute vec4 aColor;\n"
                             "void main() {\n"
                             "  gl_Position = vMatrix*vPosition;\n"
                             "  vColor=aColor;\n"
                             "}";
    char *fragmentShaderCode =
            "precision mediump float;\n"
            "varying vec4 vColor;\n"
            "void main() {\n"
            "  gl_FragColor = vColor;\n"
            "}";
    //正方体的顶点数据
    GLfloat vertices[24] = {
            -1.0f, 1.0f, 1.0f,  //正面左上0
            -1.0f, -1.0f, 1.0f,  //正面左下1
            1.0f, -1.0f, 1.0f,  //正面右下2
            1.0f, 1.0f, 1.0f,  //正面右上3
            -1.0f, 1.0f, -1.0f,  //反面左上4
            -1.0f, -1.0f, -1.0f,  //反面左下5
            1.0f, -1.0f, -1.0f,  //反面右下6
            1.0f, 1.0f, -1.0f //反面右上7
    };
    //顶点颜色
    GLfloat colors[32] = {
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            0.0f, 1.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f,
            1.0f, 0.0f, 0.0f, 1.0f
    };
    //顶点索引
    unsigned short indices[36] = {
            6, 7, 4, 6, 4, 5,  //后面
            6, 3, 7, 6, 2, 3,  //右面
            6, 5, 1, 6, 1, 2,  //下面
            0, 3, 2, 0, 2, 1,  //正面
            0, 1, 5, 0, 5, 4,  //左面
            0, 7, 3, 0, 4, 7
    };
    //视图矩阵
    glm::mat4 view;
    //投影矩阵
    glm::mat4 projection;
    //模型-视图-投影
    glm::mat4 mvp;
    float radio = 0;
    GLuint programID;

    //投影矩阵
    float mProjectMatrix[16];
    //相机位置矩阵
    float mViewMatrix[16];
    //计算变换矩阵
    float mMVPMatrix[16];


    void init() {
        if (!inited) {
            inited = true;
            glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            glEnable(GL_DEPTH_TEST);
            glDepthMask(true);
            GLuint vertexShader = loadShader(GL_VERTEX_SHADER, vertexShaderCode);
            GLuint fragmentShader = loadShader(GL_FRAGMENT_SHADER, fragmentShaderCode);
            if (vertexShader == 0 || fragmentShader == 0) {
                LOGE("着色器绑定失败");
                return;
            }
            LOGD("着色器绑定成功");
            programID = glCreateProgram();
            glAttachShader(programID, vertexShader);
            glAttachShader(programID, fragmentShader);
            //链接着色器程序
            glLinkProgram(programID);
            // 获取着色器程序链接成功与否
            GLint linkSuccess;
            glGetProgramiv(programID, GL_LINK_STATUS, &linkSuccess);
            if (linkSuccess == GL_FALSE) {
                glDeleteProgram(programID);
                return;
            }
            //使用着色器程序
            glUseProgram(programID);
        }
    }
};

#endif //INC_3DMODEL_ANGLECUBE_H
